package com.simple.business.service.evaluation.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.zuihou.base.R;
import com.github.zuihou.base.request.PageParams;
import com.github.zuihou.base.service.SuperServiceImpl;
import com.simple.business.domain.dto.evaluation.EvaluationDTO;
import com.simple.business.domain.dto.evaluation.EvaluationSaveDTO;
import com.simple.business.domain.entity.evaluation.Evaluation;
import com.simple.business.domain.entity.evaluation.EvaluationQuestion;
import com.simple.business.domain.entity.evaluation.EvaluationReport;
import com.simple.business.domain.vo.evaluation.*;
import com.simple.business.mapper.evaluation.EvaluationMapper;
import com.simple.business.mapper.evaluation.EvaluationReportMapper;
import com.simple.business.service.evaluation.EvaluationQuestionService;
import com.simple.business.service.evaluation.EvaluationReportService;
import com.simple.business.service.evaluation.EvaluationService;
import com.simple.business.service.acl.EvaluationReportACL;
import com.simple.common.utils.SecurityUtils;
import com.simple.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @desc
 * @Author Simple
 * @Date 2025/3/10 22:17
 **/
@Slf4j
@Service
@DS("toy")
public class EvaluationServiceImpl extends SuperServiceImpl<EvaluationMapper, Evaluation> implements EvaluationService {

    @Resource
    private ThreadPoolTaskExecutor executor;
    @Resource
    private EvaluationReportACL evaluationReportACL;
    @Resource
    private EvaluationReportService evaluationReportService;
    @Resource
    private EvaluationQuestionService evaluationQuestionService;

    /**
     * 保存测评结果
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> saveEvaluationReport(EvaluationSaveDTO dto) {

        //保存ai面试
        Evaluation evaluation = new Evaluation();
        BeanUtil.copyProperties(dto, evaluation);

        // 0-解析中，1-解析完成，2-异常
        evaluation.setParseStatus(0);
        evaluation.setStartTime(LocalDateTime.parse(dto.getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        evaluation.setEndTime(LocalDateTime.parse(dto.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        evaluation.setCreateTime(LocalDateTime.now());
        evaluation.setCreateUser(SecurityUtils.getUserId());
        evaluation.setDeleted(Boolean.FALSE);
        save(evaluation);

        dto.setId((Long) evaluation.getId());
        dto.setCreateEvaluationQuestionVoiceStatus(Boolean.FALSE);
        dto.setCreateUser(SecurityUtils.getUserId());

        //异步保存
        executor.execute(() -> evaluationReportACL.saveEvaluationReport(dto));

        return R.success();
    }


    /**
     * 查看用户的测评报告
     * @return
     */
    @Override
    public R<IPage<EvaluationVO>> queryEvaluations(PageParams<EvaluationDTO> params) {

        EvaluationDTO model = params.getModel();

        LambdaQueryWrapper<Evaluation> queryWrapper = Wrappers.<Evaluation>lambdaQuery().eq(Evaluation::getDeleted, Boolean.FALSE);

        if (Objects.nonNull(model.getUserId())) {
            queryWrapper.eq(Evaluation::getUserId, model.getUserId());
        }

        if (Objects.nonNull(model.getBabyId())) {
            queryWrapper.eq(Evaluation::getBabyId, model.getBabyId());
        }

        if (StringUtils.isNotEmpty(model.getStartTime())) {
            queryWrapper.ge(Evaluation::getStartTime, model.getStartTime());
        }
        if (StringUtils.isNotEmpty(model.getEndTime())) {
            queryWrapper.le(Evaluation::getEndTime, model.getEndTime());
        }
        String lastSql = String.format("order by create_time desc limit %s, %s", (params.getCurrent() - 1) * params.getSize(), params.getSize());
        queryWrapper.last(lastSql);
        List<Evaluation> evaluations = list(queryWrapper);
        List<EvaluationVO> vos = new ArrayList<>();
        for (Evaluation evaluation : evaluations) {
            EvaluationVO vo = new EvaluationVO();
            BeanUtil.copyProperties(evaluation, vo);
            vos.add(vo);
        }
        IPage<EvaluationVO> page = new Page<>(params.getCurrent(), params.getSize());
        page.setRecords(vos);
        page.setTotal(count(queryWrapper));

        return R.success(page);
    }

    /**
     * 删除测评报告
     * @param evaluationId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> deleteEvaluationReport(Long evaluationId) {

        update(Wrappers.<Evaluation>lambdaUpdate()
                .set(Evaluation::getDeleted, Boolean.TRUE)
                .eq(Evaluation::getId, evaluationId));

        evaluationReportService.update(Wrappers.<EvaluationReport>lambdaUpdate()
                .set(EvaluationReport::getDeleted, Boolean.TRUE)
                .eq(EvaluationReport::getEvaluationId, evaluationId));

        evaluationQuestionService.update(Wrappers.<EvaluationQuestion>lambdaUpdate()
                .set(EvaluationQuestion::getDeleted, Boolean.TRUE)
                .eq(EvaluationQuestion::getEvaluationId, evaluationId));
        return R.success();
    }

    /**
     * 查看测评报告
     * @param evaluationId
     * @return
     */
    @Override
    public R<EvaluationReportVO> queryEvaluationReportById(Long evaluationId) {
        EvaluationReport evaluationReport = evaluationReportService.getOne(Wrappers.<EvaluationReport>lambdaQuery()
                .eq(EvaluationReport::getEvaluationId, evaluationId)
                .eq(EvaluationReport::getDeleted, Boolean.FALSE)
                .last("order by create_time desc limit 1"));
        EvaluationReportVO vo = new EvaluationReportVO();
        BeanUtil.copyProperties(evaluationReport, vo);

        if (StringUtils.isNotEmpty(evaluationReport.getDisc())) {
            vo.setDiscVO(JSONObject.parseObject(evaluationReport.getDisc(), EvaluationReportDISCVO.class));
        }

        if (StringUtils.isNotEmpty(evaluationReport.getHolland())) {
            vo.setHollandVO(JSONObject.parseObject(evaluationReport.getHolland(), EvaluationReportHollandVO.class));
        }

        if (StringUtils.isNotEmpty(evaluationReport.getMbti())) {
            vo.setMbtiVO(JSONObject.parseObject(evaluationReport.getMbti(), EvaluationReportMBTIVO.class));
        }

        return R.success(vo);
    }


}
